package com.aiti.lulian.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.service.iml.BaseSerivceImpl;
import com.aiti.base.core.constant.MessageCodeConstant;
import com.aiti.base.core.utils.message.Message;
import com.aiti.base.core.utils.uuid.UUIDUtil;
import com.aiti.lulian.constant.VersionConstant;
import com.aiti.lulian.dto.EnterpriseDto;
import com.aiti.lulian.dto.EnterpriseSelectDto;
import com.aiti.lulian.dto.LuLianEnterpriseOperationDto;
import com.aiti.lulian.dto.SysUpload;
import com.aiti.lulian.entity.*;
import com.aiti.lulian.entity.crad.LuLianEnterpriseOperation;
import com.aiti.lulian.feign.CloudShowManagerSubService;
import com.aiti.lulian.mapper.LuLianEnterpriseHistoryMapper;
import com.aiti.lulian.mapper.LuLianEnterpriseMapper;
import com.aiti.lulian.mapper.LuLianEnterpriseUserMapper;
import com.aiti.lulian.mapper.SysUploadMapper;
import com.aiti.lulian.service.ILuLianEnterpriseService;
import com.aiti.lulian.service.ILuLianEnterpriseUserService;
import com.aiti.lulian.vo.*;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Author ZhouS
 * @CreateDate 2022-05-25
 * @Description:
 */
@Service
@Slf4j
public class LuLianEnterpriseServiceImpl extends BaseSerivceImpl<LuLianEnterpriseMapper, LuLianEnterprise> implements ILuLianEnterpriseService {

    @Autowired
    private LuLianEnterpriseMapper luLianEnterpriseMapper;
    @Resource
    private LuLianEnterpriseUserMapper enterpriseUserMapper;
    @Autowired
    private LuLianEnterpriseHistoryMapper luLianEnterpriseHistoryMapper;
    @Autowired
    private ILuLianEnterpriseUserService luLianEnterpriseUserService;

    @Autowired
    private CloudShowManagerSubService cloudShowManagerSubService;

    @Value("${operation-center.highest-privilege-users}")
    private String highestPrivilegeUsers;

    @Override
    public List<LuLianEnterprisePlantImg> getPlantImg(String enterpriseId) {

        return luLianEnterpriseMapper.getPlantImg(enterpriseId);
    }


    /**
     * 根据当前登录用户ID查询
     *
     * @param userId 用户ID
     * @return com.aiti.lulian.entity.LuLianEnterprise
     * @date 2024/6/5 0005 15:26
     * @author diaozhende
     */
    @Override
    public LuLianEnterpriseHistory queryByCurrentUser(String userId) {
        LuLianEnterpriseUser enterpriseUser = enterpriseUserMapper.selectOne(new QueryWrapper<LuLianEnterpriseUser>()
                .eq("user_id", userId)
        );
        LuLianEnterpriseHistory enterpriseHistory = new LuLianEnterpriseHistory();
        if (!BeanUtil.isEmpty(enterpriseUser)) {
            enterpriseHistory = luLianEnterpriseHistoryMapper.selectOne(new QueryWrapper<LuLianEnterpriseHistory>()
                    .eq("base_id", enterpriseUser.getEnterpriseId())
            );
        }
        return enterpriseHistory;
    }

    @Override
    public Page<LuLianEnterprise> queryPage(EnterpriseSelectDto enterpriseSelectDto) {
        Page<Object> page = new Page<>(enterpriseSelectDto.getPageNum(), enterpriseSelectDto.getPageSize());

        return luLianEnterpriseMapper.queryPage(page,enterpriseSelectDto);
    }

    @Override
    public LuLianEnterprise findByBaseId(String baseId) {
        return luLianEnterpriseMapper.selectByBaseId(baseId);
    }

    @Override
    public List<LuLianCgsOrder> findActivityOrderByBaseId(String enterpriseId) {
        return luLianEnterpriseMapper.findActivityOrderByBaseId(enterpriseId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Message saveEnterpriseUser(LuLianEnterpriseUser luLianEnterpriseUser) {
        String userId = luLianEnterpriseUser.getUserId();
        //判断如果该用户存在企业关联数据，则无法新增，直接返回提示信息
        LambdaQueryWrapper<LuLianEnterpriseUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LuLianEnterpriseUser::getUserId, userId);
        List<LuLianEnterpriseUser> enterpriseUserList = luLianEnterpriseUserService.list(wrapper);
        if (enterpriseUserList != null && enterpriseUserList.size() > 1) {
            return Message.fail("错误，该用户已关联了多家企业，请联系平台工作人员进行处理");
        } else if (enterpriseUserList != null && enterpriseUserList.size() == 1 && StrUtil.isNotBlank(luLianEnterpriseUser.getIsApp()) && "1".equals(luLianEnterpriseUser.getIsApp())) {
            return Message.fail("该用户已关联了企业【" + luLianEnterpriseHistoryMapper.selectById(enterpriseUserList.get(0).getEnterpriseId()).getBaseName() +"】");
        }
        if(!CollectionUtils.isEmpty(enterpriseUserList)) {
            LuLianEnterpriseUser existEnterpriseUser = enterpriseUserList.get(0);
            String enterpriseId = existEnterpriseUser.getEnterpriseId();
            String existsUserId = existEnterpriseUser.getUserId();
            if(!enterpriseId.equals(luLianEnterpriseUser.getEnterpriseId()) || !existsUserId.equals(userId)){
                existEnterpriseUser.setEnterpriseId(luLianEnterpriseUser.getEnterpriseId());
                existEnterpriseUser.setUserId(userId);
                luLianEnterpriseUserService.updateById(existEnterpriseUser);
            }
        }else{
            luLianEnterpriseUser.setBaseId(UUIDUtil.getUUID2());
            luLianEnterpriseUserService.save(luLianEnterpriseUser);
        }
        return Message.success();
    }

    @Override
    public Map getEnterpriseUser(String userId) {
        return this.getBaseMapper().getByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Message delEnterpriseUserByUserId(String userId, String enterpriseId) {
        LambdaQueryWrapper<LuLianEnterpriseUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LuLianEnterpriseUser::getUserId,userId).eq(LuLianEnterpriseUser::getEnterpriseId,enterpriseId);
        luLianEnterpriseUserService.remove(wrapper);
        return Message.success();
    }

    @Override
    public Message updateEnterpriseUser(LuLianEnterpriseUser luLianEnterpriseUser) {
        String userId = luLianEnterpriseUser.getUserId();
        LambdaQueryWrapper<LuLianEnterpriseUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LuLianEnterpriseUser::getUserId, userId);
        List<LuLianEnterpriseUser> list = luLianEnterpriseUserService.list(queryWrapper);
        if(!CollectionUtils.isEmpty(list)){
            LuLianEnterpriseUser existEnterpriseUser = list.get(0);
            String enterpriseId = existEnterpriseUser.getEnterpriseId();
            String existsUserId = existEnterpriseUser.getUserId();
            if(!enterpriseId.equals(luLianEnterpriseUser.getEnterpriseId()) || !existsUserId.equals(userId)){
                existEnterpriseUser.setEnterpriseId(luLianEnterpriseUser.getEnterpriseId());
                existEnterpriseUser.setUserId(userId);
                luLianEnterpriseUserService.updateById(existEnterpriseUser);
            }
        }
        return Message.success();
    }

    @Autowired
    private SysUploadMapper sysUploadMapper;

    /**
     * 查询企业Logo地址
     *
     * @param enterpriseId
     * @return
     */
    @Override
    public Map<String, String> selectEnterpriseLogo(String enterpriseId) {
        Map<String,String> resultMap = new HashMap<>(16);
        LuLianEnterprise enterprise = luLianEnterpriseMapper.selectOne(new QueryWrapper<LuLianEnterprise>().select("logo").eq("base_id", enterpriseId));
        if(enterprise != null && StringUtils.isNotBlank(enterprise.getLogo())){
            String logo = enterprise.getLogo();
            List<String> split = StrUtil.split(logo, "/");
            String s = split.get(split.size() - 1);
            SysUpload sysUpload = sysUploadMapper.selectById(s);
            if (sysUpload != null) {
                String baseUrl = sysUpload.getBaseUrl();
                resultMap.put("logoAddress",baseUrl);
            }else{
                resultMap.put("logoAddress","classpath:qrlogo.png");
            }
        }else{
            resultMap.put("logoAddress","classpath:qrlogo.png");
        }
        return resultMap;
    }

    @Override
    public Message selectEnterpriseInfoByIds(List<String> enterpriseIds) {
        LambdaQueryWrapper<LuLianEnterprise> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LuLianEnterprise::getBaseId,enterpriseIds);
        queryWrapper.select(LuLianEnterprise::getBaseName,LuLianEnterprise::getBaseId);
        List<LuLianEnterprise> luLianEnterprises = luLianEnterpriseMapper.selectList(queryWrapper);
        return Message.success(luLianEnterprises);
    }

    @Override
    public Message enterpriseVersion(EnterpriseDto dto) {
        String enterpriseId = dto.getEnterpriseId();
        String userId = dto.getUserId();
        if(StringUtils.isEmpty(enterpriseId)){
            LambdaQueryWrapper<LuLianEnterpriseUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LuLianEnterpriseUser::getUserId, userId);
            List<LuLianEnterpriseUser> list = luLianEnterpriseUserService.list(queryWrapper);
            if(!CollectionUtils.isEmpty(list)) {
                LuLianEnterpriseUser existEnterpriseUser = list.get(0);
                dto.setEnterpriseId(existEnterpriseUser.getEnterpriseId());
            }
        }
        if(StringUtils.isEmpty(enterpriseId)){
            if(!StringUtils.isEmpty(userId)){
                Message userRoleMessage = cloudShowManagerSubService.getRoleByUserId(userId);
                if (userRoleMessage == null) {
                    return Message.fail("获取角色信息失败！");
                }
                if(userRoleMessage.getCode().equals(MessageCodeConstant.MSG_FAIL_CODE)){
                    throw new RuntimeException("查询用户失败");
                }
                String roleIds = (String)userRoleMessage.getObj();
                if(!org.apache.commons.lang3.StringUtils.isEmpty(roleIds)) {
                    String[] split = roleIds.split(StrUtil.COMMA);
                    boolean systemAdmin = Arrays.stream(split).filter(f -> "1".equals(f)).count() > 0;
                    //系统管理员返回高级版
                    if (systemAdmin) {
                        return Message.success(VersionConstant.SENIOR_VERSION);
                    }else{
                        return Message.success(VersionConstant.PERSON_VERSION);
                    }
                }else{
                    return Message.success(VersionConstant.PERSON_VERSION);
                }

            }

        }else{
            LuLianEnterprise enterprise = this.getById(enterpriseId);
            if(enterprise == null){
                return Message.success(VersionConstant.PERSON_VERSION);
            }
            Integer miniProgramVersion = enterprise.getMiniProgramVersion();
            //是否是政府 0或null企业  1是政府
            String sfZf = enterprise.getSfZf();
            if(miniProgramVersion != null){
                if("1".equals(sfZf)){
                    return Message.success(VersionConstant.GOVERNMENT_VERSION);
                }else{
                    Date expireTime = enterprise.getExpireTime();
                    if (expireTime == null){
                        return Message.success(miniProgramVersion);
                    }else{
                        if(expireTime.before(new Date())){
                            //过期
                            LambdaUpdateWrapper<LuLianEnterprise> wrapper = new LambdaUpdateWrapper<>();
                            wrapper.set(LuLianEnterprise::getMiniProgramVersion,null)
                            .eq(LuLianEnterprise::getBaseId, enterpriseId);
                            this.update(wrapper);
                            return Message.success(VersionConstant.PERSON_VERSION);
                        }else{
                            //没过期
                            return Message.success(miniProgramVersion);
                        }
                    }

                }
            }else{
                if("1".equals(sfZf)){
                    return Message.success(VersionConstant.GOVERNMENT_VERSION);
                }else{
                    return Message.success(VersionConstant.PERSON_VERSION);
                }
            }

        }
        return Message.success(VersionConstant.PERSON_VERSION);
    }

    @Override
    public List<LuLianEnterprise> selectEnterpriseInfoByName(String enterpriseName) {
        if(StringUtils.isBlank(enterpriseName)){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<LuLianEnterprise> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(LuLianEnterprise::getBaseName,enterpriseName);
        queryWrapper.isNull(LuLianEnterprise::getSfZf).or().eq(LuLianEnterprise::getSfZf,"0");
        queryWrapper.select(LuLianEnterprise::getBaseId,LuLianEnterprise::getBaseName,LuLianEnterprise::getUnicode);
        return luLianEnterpriseMapper.selectList(queryWrapper);
    }

    @Override
    public String selectUserBindEnterpriseName(String userId) {
        return luLianEnterpriseMapper.selectUserBindEnterpriseName(userId);
    }

    @Override
    public List<LuLianEnterpriseOperationVo> getEnterpriseList(LuLianEnterpriseOperationDto luLianEnterpriseOperationDto, Page<LuLianEnterprise> page) {
        //创建具有查看全部数据的用户ID集
        String[] highestPrivilegeUsersArray = highestPrivilegeUsers.split(",");
        Set<String> userIdSet = Arrays.stream(highestPrivilegeUsersArray).collect(Collectors.toSet());
        if (userIdSet.contains(luLianEnterpriseOperationDto.getUserId())) {
            luLianEnterpriseOperationDto.setFlag("1");
        }
        // 设置过期时间的查询条件
        if(StrUtil.isNotEmpty(luLianEnterpriseOperationDto.getExpirationStartTime())) {
            luLianEnterpriseOperationDto.setExpirationStartTime(luLianEnterpriseOperationDto.getExpirationStartTime() + " 00:00:00");
        }
        if(StrUtil.isNotEmpty(luLianEnterpriseOperationDto.getExpirationEndTime())) {
            luLianEnterpriseOperationDto.setExpirationEndTime(luLianEnterpriseOperationDto.getExpirationEndTime() + " 23:59:59");
        }
        // 设置创建时间查询条件
        if(StrUtil.isNotEmpty(luLianEnterpriseOperationDto.getBaseCreateTimeStart())) {
            luLianEnterpriseOperationDto.setBaseCreateTimeStart(luLianEnterpriseOperationDto.getBaseCreateTimeStart() + " 00:00:00");
        }
        if(StrUtil.isNotEmpty(luLianEnterpriseOperationDto.getBaseCreateTimeEnd())) {
            luLianEnterpriseOperationDto.setBaseCreateTimeEnd(luLianEnterpriseOperationDto.getBaseCreateTimeEnd() + " 23:59:59");
        }
        // 增加两个字段：1：企业人数（这个字段原来的查询有，people_count） 2. 企业每日新增用户数（统计每个企业前一天开通名片业务的人数）
        List<LuLianEnterpriseOperationVo> operationVoList = luLianEnterpriseMapper.selectEnterpriseList(luLianEnterpriseOperationDto, page);
        if(CollectionUtil.isEmpty(operationVoList)) {
            return operationVoList;
        }
        // 前一天企业开通名片业务人员的数量
        Date yesterdayDate = DateUtil.offsetDay(new Date(), -1);
        List<EnterpriseOpenCardInfo> enterpriseOpenCardUserCountList = luLianEnterpriseMapper.selectEnterpriseOpenCardUserCount(this.getYesterdayStartTime(yesterdayDate), this.getYesterdayEndTime(yesterdayDate));
        // 前一天没有企业开通名片业务，所有的数量设置为0
        if(CollectionUtil.isEmpty(enterpriseOpenCardUserCountList)) {
            for(LuLianEnterpriseOperationVo vo : operationVoList) {
                vo.setEnterpriseOpenCardUserCount(0);
            }
            return operationVoList;
        }
        // 当前页企业是否有企业员工开通名片业务，有则设置对应数量
        for(LuLianEnterpriseOperationVo vo : operationVoList) {
            boolean exist = false;
            for(EnterpriseOpenCardInfo info : enterpriseOpenCardUserCountList) {
                if(vo.getBaseId().equals(info.getEnterpriseId())) {
                    vo.setEnterpriseOpenCardUserCount(info.getOpenCount());
                    exist = true;
                    break;
                }
            }
            if(!exist) {
                vo.setEnterpriseOpenCardUserCount(0);
            }
        }
        return operationVoList;
    }

    public void exportExcel(LuLianEnterpriseOperationDto dto, String userId, HttpServletResponse response) {
        try {
            if (StrUtil.isEmpty(userId)) {
                response.setContentType("text/html");
                response.setCharacterEncoding("utf-8");
                response.getWriter().write("请先登录系统");
                return;
            }
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode(DateUtil.now() + "运营中心表格数据", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", fileName + ".xlsx");
            response.setHeader("Access-Control-Expose-Headers","Content-Disposition");

            Page<LuLianEnterprise> page = new Page<>(1, -1);
            List<LuLianEnterpriseOperationExcelVo> exportList = this.getEnterpriseListExport(dto, page);
            EasyExcel.write(response.getOutputStream(), LuLianEnterpriseOperationExcelVo.class)
                    .autoCloseStream(true)
                    .sheet("运行中心表格数据")
                    .doWrite(exportList);
        } catch (Exception e) {
            log.error("导出Excel异常：{}", ExceptionUtil.stacktraceToString(e));
        }
    }

    @Override
    public List<EnterpriseAdminUserVo> getEnterpriseAdminUser(String enterpriseId) {
        return this.getBaseMapper().cardAdminUser(enterpriseId);
    }

    @Override
    public LuLianEnterpriseVo getEnterpriseInfoById(String enterpriseId) {
        return luLianEnterpriseMapper.selectEnterpriseInfoById(enterpriseId);
    }

    // 导出Excel
    private List<LuLianEnterpriseOperationExcelVo> getEnterpriseListExport(LuLianEnterpriseOperationDto luLianEnterpriseOperationDto, Page<LuLianEnterprise> page) {
        //创建具有查看全部数据的用户ID集
        String[] highestPrivilegeUsersArray = highestPrivilegeUsers.split(",");
        Set<String> userIdSet = Arrays.stream(highestPrivilegeUsersArray).collect(Collectors.toSet());
        if (userIdSet.contains(luLianEnterpriseOperationDto.getUserId())) {
            luLianEnterpriseOperationDto.setFlag("1");
        }
        List<LuLianEnterpriseOperationVo> list = luLianEnterpriseMapper.selectEnterpriseList(luLianEnterpriseOperationDto, page);
        if(CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 企业新增的开通名片人数
        Date yesterdayDate = DateUtil.offsetDay(new Date(), -1);
        List<EnterpriseOpenCardInfo> enterpriseOpenCardUserCountList = luLianEnterpriseMapper.selectEnterpriseOpenCardUserCount(this.getYesterdayStartTime(yesterdayDate), this.getYesterdayEndTime(yesterdayDate));
        List<LuLianEnterpriseOperationExcelVo> excelList = new ArrayList<>(1500);
        for(LuLianEnterpriseOperationVo vo : list) {
            LuLianEnterpriseOperationExcelVo excelVo = new LuLianEnterpriseOperationExcelVo();
            LuLianEnterpriseOperation enterpriseOperationInfo = vo.getEnterpriseOperationInfo();

            excelVo.setBaseName(vo.getBaseName());
            excelVo.setMiniProgramVersionTag(vo.getMiniProgramVersionTag());
            if(enterpriseOperationInfo != null) {
                excelVo.setDeliverySchedule(enterpriseOperationInfo.getDeliverySchedule());
                excelVo.setOperationHeadName(enterpriseOperationInfo.getOperationHeadName());
            }
            excelVo.setIsKeyTag(vo.getIsKeyTag());
            excelVo.setAddress(this.buildAddress(vo));
            excelVo.setTradeFirst(vo.getTradeFirst());
            excelVo.setOpenCount(vo.getOpenCount());
            excelVo.setPubCount(vo.getPubCount());
            excelVo.setViewCount(vo.getViewCount());
            excelVo.setExpirationTime(vo.getExpirationTime());
            excelVo.setPeopleCount(vo.getPeopleCount());
            if(CollectionUtil.isNotEmpty(enterpriseOpenCardUserCountList)) {
                boolean exist = false;
                for(EnterpriseOpenCardInfo info : enterpriseOpenCardUserCountList) {
                    if(vo.getBaseId().equals(info.getEnterpriseId())) {
                        excelVo.setEnterpriseOpenCardUserCount(info.getOpenCount());
                        exist = true;
                        break;
                    }
                }
                if(!exist) {
                    excelVo.setEnterpriseOpenCardUserCount(0);
                }
            }
            else {
                excelVo.setEnterpriseOpenCardUserCount(0);
            }

            excelList.add(excelVo);
        }
        return excelList;
    }

    private String buildAddress(LuLianEnterpriseOperationVo vo) {
        String address = "";
        String province = vo.getProvince();
        String city = vo.getCity();
        String county = vo.getCounty();
        if(StrUtil.isNotBlank(province) && StrUtil.isNotBlank(city) && StrUtil.isNotBlank(county)) {
            address = province + "--" + city + "-" + county;
        }else if(StrUtil.isBlank(province) && StrUtil.isNotBlank(city) && StrUtil.isNotBlank(county)) {
            address = city + "-" + county;
        }else if(StrUtil.isNotBlank(province) && StrUtil.isBlank(city) && StrUtil.isNotBlank(county)) {
            address = province + "-" + county;
        }else if(StrUtil.isNotBlank(province) && StrUtil.isNotBlank(city) && StrUtil.isBlank(county)) {
            address = province + "--" + city;
        }else if(StrUtil.isBlank(province) && StrUtil.isBlank(city) && StrUtil.isNotBlank(county)) {
            address = county;
        }else if(StrUtil.isBlank(province) && StrUtil.isNotBlank(city) && StrUtil.isBlank(county)) {
            address = city;
        }else if(StrUtil.isNotBlank(province) && StrUtil.isBlank(city) && StrUtil.isBlank(county)) {
            address = province;
        }
        return address;
    }

    private String getYesterdayStartTime(Date yesterdayDate) {
        return DateUtil.format(DateUtil.beginOfDay(yesterdayDate), "yyyy-MM-dd HH:mm:ss");
    }

    private String getYesterdayEndTime(Date yesterdayDate) {
        return DateUtil.format(DateUtil.endOfDay(yesterdayDate), "yyyy-MM-dd HH:mm:ss");
    }

}